package jfox.platform.function.action;

import java.util.ArrayList;
import java.util.List;
import javax.ejb.EJB;

import jfox.platform.function.bo.NodeBO;
import jfox.platform.function.entity.Node;
import jfox.platform.infrastructure.SuperAction;
import org.jfox.framework.annotation.Service;
import org.jfox.mvc.ActionContext;
import org.jfox.mvc.Invocation;
import org.jfox.mvc.annotation.ActionMethod;
import org.jfox.mvc.validate.LongValidation;
import org.jfox.mvc.validate.StringValidation;

/**
 * @author <a href="mailto:jfox.young@gmail.com">Young Yang</a>
 */
@Service(id = "node")
public class NodeAction extends SuperAction {

    @EJB
    NodeBO nodeBO;

    @ActionMethod(name = "mgmt", successView = "platform/function/node_management.vhtml")
    public void listNodeTree(ActionContext actionContext) throws Exception {

    }


    @ActionMethod(name = "newview", successView = "platform/function/node_new.vhtml")
    public void newNodeView(ActionContext actionContext) throws Exception {
//        System.out.println("!!! Hello, " + invocationContext.getFullActionMethodName());
    }

    @ActionMethod(name = "editview", successView = "platform/function/node_edit.vhtml", invocationClass = DeleteNodeInvocation.class)
    public void editNodeView(ActionContext actionContext) throws Exception {
        DeleteNodeInvocation invocation = (DeleteNodeInvocation)actionContext.getInvocation();
        Node node = nodeBO.getNodeById(invocation.getId());
        actionContext.getPageContext().setAttribute("node", node);
    }

    @ActionMethod(name = "new", successView = "include/json_response.vhtml", errorView = "include/json_response.vhtml", invocationClass = NewNodeInvocation.class)
    public void newNode(ActionContext actionContext) throws Exception {
        NewNodeInvocation invocation = (NewNodeInvocation)actionContext.getInvocation();
        Node node = new Node();
        node.setRootId(invocation.getRootId());
        node.setParentId(invocation.getParentId());
        node.setBindAction(invocation.getBindAction());
        node.setIcon(invocation.getIcon());
        // set creator
        node.setCreator(getUserContext().getUsername());
        node.setDescription(invocation.getDescription());
        node.setIcon(invocation.getIcon());
        String localName = "";
        if (invocation.getLocalName_en_US() != null && invocation.getLocalName_en_US().trim().length() > 0) {
            localName += "en_US=" + invocation.getLocalName_en_US();
        }
        if (invocation.getLocalName_zh_CN() != null && invocation.getLocalName_zh_CN().trim().length() > 0) {
            if (localName.length() > 0) {
                localName += "\n";
            }
            localName += "zh_CN=" + invocation.getLocalName_zh_CN();
        }
        if (invocation.getLocalName_zh_TW() != null && invocation.getLocalName_zh_TW().trim().length() > 0) {
            if (localName.length() > 0) {
                localName += "\n";
            }
            localName += "zh_TW=" + invocation.getLocalName_zh_TW();
        }
        node.setLocalName(localName);
        node.setName(invocation.getName());
        node.setPriority(invocation.getPriority());
        node.setVstatus(invocation.getVstatus());
        node.setType(invocation.getType());
        node.setCrud(invocation.getCrud());
        node.setNodeGroup(invocation.getNodeGroup());
        nodeBO.newNode(node);
        actionContext.getPageContext().setAttribute(JSON_RESPONSE_OBJ, node);
    }

    @ActionMethod(name = "edit", successView = "include/json_response.vhtml", invocationClass = EditNodeInvocation.class)
    public void editNode(ActionContext actionContext) throws Exception {
        EditNodeInvocation invocation = (EditNodeInvocation)actionContext.getInvocation();
        Node node = nodeBO.getNodeById(invocation.getId());
        node.setRootId(invocation.getRootId());
        node.setParentId(invocation.getParentId());
        node.setBindAction(invocation.getBindAction());
        node.setIcon(invocation.getIcon());
        node.setDescription(invocation.getDescription());
        node.setIcon(invocation.getIcon());
        String localName = "";
        if (invocation.getLocalName_en_US() != null && invocation.getLocalName_en_US().trim().length() > 0) {
            localName += "en_US=" + invocation.getLocalName_en_US();
        }
        if (invocation.getLocalName_zh_CN() != null && invocation.getLocalName_zh_CN().trim().length() > 0) {
            if (localName.length() > 0) {
                localName += "\n";
            }
            localName += "zh_CN=" + invocation.getLocalName_zh_CN();
        }
        if (invocation.getLocalName_zh_TW() != null && invocation.getLocalName_zh_TW().trim().length() > 0) {
            if (localName.length() > 0) {
                localName += "\n";
            }
            localName += "zh_TW=" + invocation.getLocalName_zh_TW();
        }
        node.setLocalName(localName);
        node.setName(invocation.getName());
        node.setPriority(invocation.getPriority());
        node.setVstatus(invocation.getVstatus());
        node.setType(invocation.getType());
        node.setCrud(invocation.getCrud());
        node.setNodeGroup(invocation.getNodeGroup());
        // set lastModifier
        node.setLastModifier(getUserContext().getUsername());
        nodeBO.updateNode(node);

        actionContext.getPageContext().setAttribute(JSON_RESPONSE_OBJ, node);
    }

    @ActionMethod(name = "delete", successView = "include/json_response.vhtml", errorView = "include/json_response.vhtml", invocationClass = DeleteNodeInvocation.class)
    public void deleteNode(ActionContext actionContext) throws Exception {
        DeleteNodeInvocation invocation = (DeleteNodeInvocation)actionContext.getInvocation();
        actionContext.getPageContext().setAttribute(JSON_RESPONSE_OBJ, invocation.getId());
        nodeBO.deleteNode(invocation.getId());
/*
        try {
            nodeBO.deleteNode(invocation.getId());
            JSONResponse jsonResponse = JSONResponse.createSuccessJSONResponse(null);
            invocationContext.getPageContext().setAttribute(JSON_RESPONSE, jsonResponse);
        }
        catch (Exception e) {
            JSONResponse jsonResponse = JSONResponse.createFailureJSONResponse(null, e);
            invocationContext.getPageContext().setAttribute(JSON_RESPONSE, jsonResponse);
            logger.error("failed to delete node: " +  invocation.getId(), e);
        }
*/
    }

    @ActionMethod(name = "getchilds", successView = "include/json_response.vhtml", invocationClass = GetChildsNodeInvocation.class)
    public void getChildNodes(ActionContext actionContext) throws Exception {
        GetChildsNodeInvocation invocation = (GetChildsNodeInvocation)actionContext.getInvocation();
        List<Node> childNodes = new ArrayList<Node>();
        if(invocation.getNode() == 0) { // 根节点
            childNodes.addAll(nodeBO.getModuleNodes());
        }
        else {
            childNodes.addAll(nodeBO.getChildNodes(invocation.getNode()));
        }
        actionContext.getPageContext().setAttribute(JSON_RESPONSE_OBJ, childNodes);
    }

    public static class NewNodeInvocation extends Invocation {
        private long rootId;
        private long parentId;

        @StringValidation(minLength = 2)
        private String name;
        private String localName_en_US;
        private String localName_zh_CN;
        private String localName_zh_TW;

        private String bindAction;
        private String icon;
        private int priority;
        private int vstatus;

        private String description;

        private byte type;
        private byte crud;
        private String nodeGroup;

        public long getRootId() {
            return rootId;
        }

        public void setRootId(long rootId) {
            this.rootId = rootId;
        }

        public long getParentId() {
            return parentId;
        }

        public void setParentId(long parentId) {
            this.parentId = parentId;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getLocalName_en_US() {
            return localName_en_US;
        }

        public void setLocalName_en_US(String localName_en_US) {
            this.localName_en_US = localName_en_US;
        }

        public String getLocalName_zh_CN() {
            return localName_zh_CN;
        }

        public void setLocalName_zh_CN(String localName_zh_CN) {
            this.localName_zh_CN = localName_zh_CN;
        }

        public String getLocalName_zh_TW() {
            return localName_zh_TW;
        }

        public void setLocalName_zh_TW(String localName_zh_TW) {
            this.localName_zh_TW = localName_zh_TW;
        }

        public String getBindAction() {
            return bindAction;
        }

        public void setBindAction(String bindAction) {
            this.bindAction = bindAction;
        }

        public String getIcon() {
            return icon;
        }

        public void setIcon(String icon) {
            this.icon = icon;
        }

        public int getPriority() {
            return priority;
        }

        public void setPriority(int priority) {
            this.priority = priority;
        }

        public int getVstatus() {
            return vstatus;
        }

        public void setVstatus(int vstatus) {
            this.vstatus = vstatus;
        }

        public String getDescription() {
            return description;
        }

        public void setDescription(String description) {
            this.description = description;
        }

        public byte getType() {
            return type;
        }

        public void setType(byte type) {
            this.type = type;
        }

        public byte getCrud() {
            return crud;
        }

        public void setCrud(byte crud) {
            this.crud = crud;
        }

        public String getNodeGroup() {
            return nodeGroup;
        }

        public void setNodeGroup(String nodeGroup) {
            this.nodeGroup = nodeGroup;
        }
    }



    public static class DeleteNodeInvocation extends Invocation {

        @LongValidation
        private long id;

        public long getId() {
            return id;
        }

        public void setId(long id) {
            this.id = id;
        }
    }

    public static class EditNodeInvocation extends NewNodeInvocation {

        private long id;

        public long getId() {
            return id;
        }

        public void setId(long id) {
            this.id = id;
        }
    }

    public static class GetChildsNodeInvocation extends Invocation {

        @LongValidation
        private long node;

        public long getNode() {
            return node;
        }

        public void setNode(long node) {
            this.node = node;
        }
    }

}